library Dto requires /*
    */ TimerUtils /*
    */ TriggerUtils /*
    */ GroupUtils /*
    */ 

    private type UnitArray extends unit array [8]
    private type EffectArray extends effect array [8]
    private type RealArray extends real array [8]
    private type IntegerArray extends integer array [8]
    private type StringArray extends string array [8]
    private type BooleanArray extends boolean array [8]

    struct Dto
        timer m_timer
        trigger m_trigger
        player m_player
        item m_item
        effect m_effect
        unit m_unit
        group m_group
        texttag m_texttag
        lightning m_lightning
        triggeraction m_action
        triggercondition m_condition
        string m_string
        boolean m_boolean
        real m_real
        integer m_int

        integer m_data
        string m_path

        real m_real1
        real m_real2
        real m_real3
        real m_real4

        integer m_int1
        integer m_int2
        integer m_int3
        integer m_int4

        unit m_unit1
        unit m_unit2
        unit m_unit3
        unit m_unit4

        UnitArray m_units
        EffectArray m_effects
        RealArray m_reals
        IntegerArray m_integers
        StringArray m_strings
        BooleanArray m_booleans

        private method reset takes nothing returns nothing
            set m_timer = null
            set m_trigger = null
            set m_player = null

            set m_unit = null

            set m_item = null

            set m_effect = null
            set m_string = null

            set m_real = 0.00
            set m_int = 0

            set m_path = null
            set m_data = 0

            set m_boolean = false

            set m_group = null
            set m_texttag = null
            set m_lightning = null
            set m_action = null
            set m_condition = null

            set m_units = 0
            set m_effects = 0
            set m_reals = 0
            set m_integers = 0
            set m_strings = 0
            set m_booleans = 0

            set m_real1 = 0.00
            set m_real2 = 0.00
            set m_real3 = 0.00
            set m_real4 = 0.00

            set m_int1 = 0
            set m_int2 = 0
            set m_int3 = 0
            set m_int4 = 0

            set m_unit1 = null
            set m_unit2 = null
            set m_unit3 = null
            set m_unit4 = null
        endmethod

        static method create takes nothing returns Dto
            local Dto this = Dto.allocate()
            call this.reset()
            return this
        endmethod

        private method hasArray takes nothing returns boolean
            if this.m_effects == 0 and this.m_units == 0 and this.m_reals == 0 /*
                */ and this.m_integers == 0 and this.m_strings == 0 and this.m_booleans == 0 then
                return false
            endif
            return true
        endmethod

        private method destroyArray takes nothing returns nothing
            local integer i
            set i = 0
            loop
                exitwhen i >= 8
                if this.m_effects[i] != null then
                    call DestroyEffect(this.m_effects[i])
                endif
                set this.m_effects[i] = null
                
                set this.m_units[i] = null
                set this.m_strings[i] = null
                set i = i + 1
            endloop

            if this.m_effects > 0 then
                call this.m_effects.destroy()
            endif
            if this.m_units > 0 then
                call this.m_units.destroy()
            endif
            if this.m_reals > 0 then
                call this.m_reals.destroy()
            endif
            if this.m_integers > 0 then
                call this.m_integers.destroy()
            endif
            if this.m_strings > 0 then
                call this.m_strings.destroy()
            endif
        endmethod

        method destroy takes nothing returns nothing
            if this.m_timer != null then
                call ReleaseTimer(this.m_timer)
            endif
            if this.m_trigger != null then
                call ReleaseTrigger(this.m_trigger)
            endif
            if this.m_group != null then
                call ReleaseGroup(this.m_group)
            endif
            if this.m_effect != null then
                call DestroyEffect(this.m_effect)
            endif
            if this.hasArray() then
                call this.destroyArray()
            endif
            call this.reset()
            call this.deallocate()
        endmethod

        private static method anon__0 takes nothing returns nothing
            local Dto this = ReleaseTimer(GetExpiredTimer())
            call this.destroy()
        endmethod

        method delayDestroy takes real timeout returns nothing
            call TimerStart(NewTimerEx(this), timeout, false, function thistype.anon__0)
        endmethod

        method getEffects takes integer index returns effect
            return this.m_effects[index]
        endmethod

        method setEffects takes integer index, effect eff returns nothing
            if this.m_effects == 0 then
                set this.m_effects = EffectArray.create()
            endif
            set this.m_effects[index] = eff
        endmethod

        method getUnits takes integer index returns unit
            return this.m_units[index]
        endmethod

        method setUnits takes integer index, unit u returns nothing
            if this.m_units == 0 then
                set this.m_units = UnitArray.create()
            endif
            set this.m_units[index] = u
        endmethod

        method getReals takes integer index returns real
            return this.m_reals[index]
        endmethod

        method setReals takes integer index, real r returns nothing
            if this.m_reals == 0 then
                set this.m_reals = RealArray.create()
            endif
            set this.m_reals[index] = r
        endmethod

        method getIntegers takes integer index returns integer
            return this.m_integers[index]
        endmethod

        method setIntegers takes integer index, integer i returns nothing
            if this.m_integers == 0 then
                set this.m_integers = IntegerArray.create()
            endif
            set this.m_integers[index] = i
        endmethod

        method getStrings takes integer index returns string
            return this.m_strings[index]
        endmethod

        method setStrings takes integer index, string str returns nothing
            if this.m_strings == 0 then
                set this.m_strings = StringArray.create()
            endif
            set this.m_strings[index] = str
        endmethod

        method getBooleans takes integer index returns boolean
            return this.m_booleans[index]
        endmethod

        method setBooleans takes integer index, boolean bl returns nothing
            if this.m_booleans == 0 then
                set this.m_booleans = BooleanArray.create()
            endif
            set this.m_booleans[index] = bl
        endmethod

        method getDataTimer takes integer data returns timer
            if this.m_timer == null then
                set this.m_timer = NewTimer()
                call SetTimerData(this.m_timer, data)
            endif
            return this.m_timer
        endmethod

        method getTimer takes nothing returns timer
            return getDataTimer(this)
        endmethod

        method getDataTrigger takes integer data returns trigger
            if this.m_trigger == null then
                set this.m_trigger = NewTrigger()
                call SetTriggerData(this.m_trigger, data)
            endif
            return this.m_trigger
        endmethod

        method getTrigger takes nothing returns trigger
            return getDataTrigger(this)
        endmethod

        method getGroup takes nothing returns group
            if this.m_group == null then
                set this.m_group = NewGroup()
            endif
            return this.m_group
        endmethod
    endstruct

endlibrary